/**
 * Class Template
 * This class create html from js template and data object
 * Example:
 * //template text
 * // <p><%=name%></p>
 * var template = new Template("template-id", {name: "data"});
 * template.getHtml();
 * // result -> <p>data</p>
 */
Template = (function() {

    /**
     * Template constructor
     * create template and return html
     * @param id {String} template id
     * @param data {Object} template data
     * @returns {*}
     * @constructor
     */
    function Template(id, data) {
        this.id = id;
        this.cache = {};
        return this.html = this.load(this.id, data || {});
    }
    /**
     * Get created html
     * @returns {String} created html from template
     */
    Template.prototype.getHTML = function() {
        return this.html;
    };
    /**
     * Create html from template and data
     * @param str {String} template or template id
     * @param data {Object} template data
     * @returns {String}
     */
    Template.prototype.load = function(str, data) {
        var fn;
        fn = /^[0-9a-z_-]+$/i.test(str) ?
            this.cache[str] = this.cache[str] || this.load(document.getElementById(str).innerHTML) :
            new Function("obj",
                "var p=[],\
                    print=function(){\
                        p.push.apply(p,arguments);\
                    };\
                with(obj){\
                    p.push('" +
                    str.replace(/[\r\t\n]/g, " ")
                        .split("<%").join("\t")
                        .replace(/((^|%>)[^\t]*)'/g, "$1\r")
                        .replace(/\t=(.*?)%>/g, "',$1,'")
                        .split("\t").join("');")
                        .split("%>").join("p.push('")
                        .split("\r").join("\\'")
                    + "');\
                }\
                return p.join('');"
            );
        return data ? fn(data) : fn;
    };

    return Template;

})();